import requests
from flask import render_template, redirect, request, current_app, \
    url_for, g, send_from_directory, abort, flash, jsonify,make_response
from flask_login import login_user, logout_user, login_required, current_user

from . import main
from app.models import Article, Tag, Category, article_tag, Recommend, User, \
     InvitationCode, OnlineTool, Comment,Order
from .forms import SearchForm, LoginForm,RegistForm, PasswordForm, InviteRegistForm, \
    CommentForm
from app.extensions import db
from ..import db, sitemap
from app.util import get_bing_img_url
from app.alipay import AliPay, DCAliPay, ISVAliPay
from app.alipay.utils import AliPayConfig
import time
import random

from wechatpy import parse_message, create_reply,WeChatClient
from wechatpy.utils import check_signature
from wechatpy.exceptions import (
    InvalidSignatureException,
    InvalidAppIdException,
)


@main.before_request
def before_request():
    if '/css/' in request.path or '/js/' in request.path or '/img/' in request.path:
        return
    g.tags = Tag.query.all()
    g.categorys = Category.query.all()
    g.recent_articles = Article.query.filter(Article.state ==1).order_by(Article.timestamp.desc()).limit(10).all()
    g.search_form = SearchForm(prefix='search')


@main.route('/', methods=['GET'])
def index():
    page = request.args.get('page', 1, type=int)
    articles = Article.query.filter_by(state=1). \
        order_by(Article.timestamp.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)

    recommends = Recommend.query.filter(Recommend.state == 1).order_by(Recommend.sn.desc()).all()
    return render_template('index.html', articles=articles, recommends = recommends)

@main.route('/favicon.ico')
def favicon():
    return main.send_static_file('img/favicon.ico')

@main.route('/hot/',methods=['GET'])
def hot():
    page = request.args.get('page',1,type=int)
    articles = Article.query.filter_by(state=1). \
        order_by(Article.vc.desc()). \
        paginate(page,per_page=current_app.config['BLOG_POST_PER_PAGE'],error_out=False)
    recommends = Recommend.query.filter(Recommend.state == 1).order_by(Recommend.sn.desc()).all()
    return render_template('index.html',articles=articles, recommends = recommends)

@main.route('/about/', methods=['GET', 'POST'])
def about():
    article = Article.query.filter(Article.name=='about-me').first()
    if article:
        article.vc = article.vc + 1
        return render_template('article.html', article=article)
    return render_template('about.html')


@main.route('/article/<name>/', methods=['GET', 'POST'])
def article(name):
    article = Article.query.filter_by(name=name).first()
    if article is None:
        abort(404)
    category = article.category
    if category.name == 'VIP' and current_user.is_anonymous:
        flash({'error': 'VIP课程需要用户登录后学习！'})
        return redirect('/login')
    if category.name == 'VIP' and current_user.is_authenticated:
        u = User.query.filter_by(id=current_user.id).first()
        if u.is_vip_expire():
            flash({'error': 'VIP课程需要充值月卡后进行学习！'})
            return redirect('/profile')
    article.vc = article.vc + 1
    db.session.commit()
    return render_template('article.html', article=article)

@main.route('/tags/')
def tags():
    tags = Tag.query.all()
    return render_template('tags.html',tags = tags)


@main.route('/tag/<t>/', methods=['GET'])
def tag(t):
    page = request.args.get('page', 1, type=int)
    tag = Tag.query.filter_by(name=t).first()
    articles = tag.articles.filter(Article.state == 1).\
        order_by(Article.timestamp.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)
    return render_template('tag.html', articles=articles, tag=tag,orderby='time')

@main.route('/tag/<t>/hot/', methods=['GET'])
def tag_hot(t):
    page = request.args.get('page', 1, type=int)
    tag = Tag.query.filter_by(name=t).first()
    articles = tag.articles.filter(Article.state == 1).\
        order_by(Article.vc.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)
    return render_template('tag.html', articles=articles, tag=tag,orderby='hot')


@main.route('/category/<c>/', methods=['GET', 'POST'])
def category(c):
    """
    文章分类列表
    """
    page = request.args.get('page', 1, type=int)
    cty = Category.query.filter_by(name=c).first()
    articles = Article.query.filter_by(category=cty,state=1).order_by(Article.timestamp.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)

    return render_template('category.html', articles=articles, category=cty,orderby='time')

@main.route('/category/<c>/hot/', methods=['GET', 'POST'])
def category_hot(c):
    page = request.args.get('page', 1, type=int)
    cty = Category.query.filter_by(name=c).first()
    articles = Article.query.filter_by(category=cty,state=1).order_by(Article.vc.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)

    return render_template('category.html', articles=articles, category=cty,orderby='hot')

@main.route('/comment/add/', methods=['GET', 'POST'])
@login_required
def comment_add():
    form = CommentForm()
    ret = {}
    ret['code'] = 0
    if form.validate_on_submit():
        c = Comment()
        form.populate_obj(c)
        c.user_id = current_user.id
        db.session.add(c)
        a = Article.query.filter(Article.id == c.article_id).first()
        a.comment_num = a.comments.count()
        db.session.commit()
        ret['code'] = 1
        ret['id'] = c.id

    return jsonify(ret)

@main.route('/archive/',methods=['GET'])
def archive():
    """
    根据时间归档
    """
    articles = Article.query.filter_by(state=1).order_by(Article.timestamp.desc()).all()
    time_tag = []
    current_tag = ''
    for a in articles:
        a_t = a.timestamp.strftime('%Y-%m')
        if  a_t != current_tag:
            tag = dict()
            tag['name'] = a_t
            tag['articles'] = []
            time_tag.append(tag)
            current_tag = a_t
        tag = time_tag[-1]
        tag['articles'].append(a)
    return render_template('archives.html',time_tag = time_tag)

@main.route('/search/', methods=['POST'])
def search():
    if not g.search_form.validate_on_submit():
        return redirect(url_for('.index'))

    return redirect(url_for('.search_results', query=g.search_form.search.data.strip()))


@main.route('/search_results/<query>', methods=['GET', 'POST'])
def search_results(query):
    page = request.args.get('page', 1, type=int)
    articles = Article.query.filter(Article.content_html.like('%%%s%%' % query), Article.state == 1).order_by(Article.timestamp.desc()). \
        paginate(page, per_page=current_app.config['BLOG_POST_PER_PAGE'], error_out=False)
    return render_template('search_result.html', articles=articles, query=query)

@sitemap.register_generator
def sitemap():
    """
    sitemap生成
    """
    articles = Article.query.filter(Article.state == 1).all()
    categories = Category.query.all()
    tags = Tag.query.all()
    import datetime
    now = datetime.datetime.now()
    #首页
    yield 'main.index',{},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',1.0
    #关于我
    yield 'main.about',{},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.5
    #分类
    for category in categories:
        yield 'main.category',{'c':category.name},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.9
    for categories in categories:
        yield 'main.category_hot',{'c':category.name},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.9
    #标签
    yield 'main.tags',{},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.9
    for t in tags:
        yield 'main.tag',{'t':t.name},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.9
    for t in tags:
        yield 'main.tag_hot',{'t':t.name},now.strftime('%Y-%m-%dT%H:%M:%S'),'always',0.9

    #文章
    for a in articles:
        #posts.post是文章视图的endpoint,后面是其参数
        yield 'main.article',{'name':a.name}

@main.route('/robots.txt')
def robots():
    return send_from_directory(main.static_folder,'robots.txt')

@main.route('/tool/')
def tool():
    tools = OnlineTool.query.order_by(OnlineTool.sn.desc()). \
        filter(OnlineTool.state == True).all()
    return render_template('tool.html',tools = tools)


@main.route('/login', methods=['GET', 'POST'])
def login():
    login_form = LoginForm(prefix='login')
    if login_form.validate_on_submit():
        u = User.query.filter_by(username=login_form.username.data.strip()).first()
        if u is None:
            flash({'error': '帐号未注册！'})
        elif u is not None and u.verify_password(login_form.password.data.strip()) and u.status:
            login_user(user=u, remember=login_form.remember_me.data)
            flash({'success':'欢迎{}登录成功'.format(u.username)})
            return redirect(request.args.get('next',url_for('main.index')))
        elif not u.status:
            flash({'error': '用户已被管理员注销！'})
        elif not u.verify_password(login_form.password.data.strip()):
            flash({'error': '密码不正确！'})

    return render_template('login.html', form=login_form)

@main.route('/regist', methods=['GET', 'POST'])
def regist():
    '''
    注册
    '''
    is_use_invite_code = current_app.config['H3BLOG_REGISTER_INVITECODE']
    form = RegistForm(prefix='regist')
    if is_use_invite_code:
        form = InviteRegistForm(prefix='regist')
    if form.validate_on_submit(): 
        u = User(username=form.username.data.strip(),
                email=form.email.data.strip(),
                password=form.password.data.strip(),
                status=True, role=False
                )
        db.session.add(u)
        if is_use_invite_code:
            ic = InvitationCode.query.filter(InvitationCode.code == form.code.data.strip()).first()
            if ic :
                ic.user = u.username
                ic.state = False
        
        db.session.commit()
        login_user(user=u)
        flash({'success':'欢迎{}注册成功'.format(u.username)})
        return redirect(request.args.get('next',url_for('main.index')))
    return render_template('regist.html',form=form)

@main.route('/logout')
@login_required
def logout():
    """退出系统"""
    logout_user()
    return redirect(url_for('main.index'))

@main.route('/profile/',methods=['GET'])
def profile():
    '''个人信息'''
    # 用户先登录
    if current_user.is_anonymous:
        return redirect('/login?next=profile')

    # 生成支付信息
    trade_no = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())) + str(random.randint(10000, 99999))
    good_name = '亲子英语月卡VIP'
    amount = 100
    order_state = 0
    user_id = current_user.id
    order = Order(id=trade_no, good_name=good_name, amount=amount, order_state=order_state, user_id=user_id)
    db.session.add(order)
    db.session.commit()
    alipay = AliPay()
    page_order_string = alipay.api_alipay_trade_page_pay(
        out_trade_no=trade_no,
        total_amount=amount,
        subject=good_name,
        return_url='http://qinziyingyu.ruimajiaoyu.com/category/VIP'
    )
    wap_order_string = alipay.api_alipay_trade_wap_pay(
        out_trade_no=trade_no,
        total_amount=amount,
        subject=good_name,
        return_url='http://qinziyingyu.ruimajiaoyu.com/category/VIP'
    )
    user_agent = request.headers.get("User-Agent")
    print(user_agent)
    keywords = ["Android", "iPhone", "MicroMessenger"]
    for keyword in keywords:
        if user_agent.find(keyword) > 0:
            order_string = wap_order_string
            break
    else:
        order_string = page_order_string
    pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(order_string)

    return render_template('profile.html', pay_url=pay_url)

@main.route('/pay.htm',methods=['GET'])
def pay_htm():
    render_template('pay.htm')

@main.route('/password',methods=['GET','POST'])
def password():
    '''修改密码'''
    form = PasswordForm()
    if form.validate_on_submit():
        if current_user.verify_password(form.pwd.data):
            current_user.password = form.password.data
            db.session.commit()
        flash({'success':'修改密码成功'})
        return redirect(url_for('.profile'))
    return render_template('password.html',form=form)


@main.route('/bing_bg')
def bing_bg():
    '''
    获取背景地址
    '''
    return redirect(get_bing_img_url())


# 接受支付宝异步消息
@main.route('/alipay/notify', methods=['POST'])
def alipay_notify():
    '''接收支付宝回调交易信息'''
    data = request.form.to_dict()
    trade_id = data.pop("out_trade_no")
    order = Order.query.filter_by(id=trade_id).first()
    if order is None:
        return make_response('fail', 400)
    else:
        order.order_state = 1
        db.session.add(order)
        db.session.commit()
        u = User.query.filter_by(id=order.user_id).first()
        u.vip_charge_time()
    return make_response('success', 200)


# 微信公众号平台回调
@main.route("/wechat", methods=["GET", "POST"])
def wechat():
    signature = request.args.get("signature", "")#微信加密签名，signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    timestamp = request.args.get("timestamp", "")#时间戳
    nonce = request.args.get("nonce", "")#随机数
    try:
        check_signature(current_app.config['WECHAT_TOKEN'], signature, timestamp, nonce)
    except InvalidSignatureException:
        abort(403)
    if request.method == "GET":
        echo_str = request.args.get("echostr", "")
        return echo_str

    # POST request
    msg = parse_message(request.data)
    # 发送文字,默认做查询所有的文章库
    if msg.type == 'event':
        if msg.event == 'subscribe':
            reply = create_reply("欢迎您关注亲子英语,回复文字您就可以轻松搜索相关课程!", msg)
        elif msg.event == 'unsubscribe':
            reply = create_reply("感谢您关注亲子英语学习平台,再见!", msg)
    elif msg.type == "text":
        if msg.content == '分类' or msg.content == '课程':
            reply = create_reply("课程分类列表:\n"
                                 "0-18月 http://qinziyingyu.ruimajiaoyu.com/category/0-18/\n"
                                 "1.5-3岁 http://qinziyingyu.ruimajiaoyu.com/category/1.5-3/\n"
                                 "3-4岁 http://qinziyingyu.ruimajiaoyu.com/category/3-4/\n"
                                 "4-6岁 http://qinziyingyu.ruimajiaoyu.com/category/4-6/\n"
                                 "6岁以上 http://qinziyingyu.ruimajiaoyu.com/category/6plus/\n"
                                 "VIP http://qinziyingyu.ruimajiaoyu.com/category/VIP/\n", msg)
        elif msg.content == '老师' or msg.content == '教师':
            reply = create_reply("老师介绍: http://qinziyingyu.ruimajiaoyu.com/category/teachers/", msg)
        else:
            from wechatpy.replies import ArticlesReply
            reply = ArticlesReply(message=msg)
            reply.add_article({
                'title': '站内搜索关键字:{}'.format(msg.content),
                'description': '请点击此图文链接查看搜索结果',
                'image': 'http://qinziyingyu.ruimajiaoyu.com/admin/uploads/20210409171829.jpg',
                'url': 'http://qinziyingyu.ruimajiaoyu.com/search_results/{}'.format(msg.content)
            })
    else:
        reply = create_reply("请发送文字信息,其他类型消息服务端无法处理!", msg)
    return reply.render()


# @main.route("/get_access_token", methods=["GET", "POST"])

# def get_access_token():
#     api_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx593de61fc75df4bd&secret=917fb96f7293a2372a7c21fb87abfec5 '  # grant_type为固定值
#     # data = {'appid': 'wx593de61fc75df4bd',
#     #         'secret': '917fb96f7293a2372a7c21fb87abfec5'}
#     access = requests.get(api_url)
#     if access.status_code == 200:
#         str_access = access.text
#         token = (json.loads(str_access)).get('access_token')
#     return token
#     if token is None:
#         return make_response('fail', 400)
#     else:
#         access_token = token
#         db.session.add(access_token)
#         db.session.commit()
#     return make_response('success', 200)


#
# @main.route("/create_menu", methods=["GET", "POST"])
# def create_menu():
#     client = WeChatClient("wx593de61fc75df4bd", "917fb96f7293a2372a7c21fb87abfec5",access_token='45_t8G9iDJ3AIB79mrAhGYoV_hL5Z3UZHDUh7_2XImexWEwLcCbbg-4RUfeqFSiS2_oUKVUpPasyDf3gNply3RZR4byHFvVLkVpMOu1uGbiiIAZm1h-h8FBAjq6DpVIrf5i5FR3u3w53OTMRKFTAAXjABAJJG')
#     client.menu.add_conditional({
#         "button":[
#             {
#                 "name": "分类",
#                 "sub_button": [
#                     {
#                         "type": "view",
#                         "name": "0-18个月",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/0-18/"
#                     },
#                     {
#                         "type": "view",
#                         "name": "1.5-3岁",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/1.5-3/"
#                     },
#                     {
#                         "type": "view",
#                         "name": "3-4岁",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/3-4/"
#                     },
#                     {
#                         "type": "view",
#                         "name": "4-6岁",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/4-6/"
#                     },
#                     {
#                         "type": "view",
#                         "name": "6岁以上",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/6plus/"
#                     },
#                     {
#                         "type": "view",
#                         "name": "师资力量",
#                         "url": "http://qinziyingyu.ruimajiaoyu.com/category/teachers/"
#                     }
#                 ]
#             },
#             {
#                 "type":"view",
#                 "name":"VIP课程",
#                 "url": "http://qinziyingyu.ruimajiaoyu.com/category/VIP/"
#             },
#             {
#                 "type":"view",
#                 "name":"关于我们",
#                 "url": "http://qinziyingyu.ruimajiaoyu.com/category/about/"
#             },
#
#         ]
#
#     })


